// RomHeader.cs:
// Header of Nintendo DS ROM.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License.
// See LICENSE for more information.

using System;
using System.IO;

namespace SharpNitroLib.NDS
{
	/// <summary>
	/// Header of Nintendo DS ROM.
	/// </summary>
    public class RomHeader
    {
        public String Gamecode { get; set;}
        char[] makercode = new char[2];
        byte unitcode;
        byte devicetype;		// type of device in the game card
        byte devicecap;		// capacity
        byte[] reserved1 = new byte[9];
        byte romversion;
        byte reserved2;
        UInt32 arm9_rom_offset;
        UInt32 arm9_entry_address;
        UInt32 arm9_ram_address;
        UInt32 arm9_size;
        UInt32 arm7_rom_offset;
        UInt32 arm7_entry_address;
        UInt32 arm7_ram_address;
        UInt32 arm7_size;
        public UInt32 fnt_offset;
        UInt32 fnt_size;
        public UInt32 fat_offset;
        UInt32 fat_size;
        UInt32 arm9_overlay_offset;
        UInt32 arm9_overlay_size;
        UInt32 arm7_overlay_offset;
        UInt32 arm7_overlay_size;
        byte[] rom_control_info1 = new byte[8];
        UInt32 icon_title_offset;
        UInt16 secure_area_crc;
        UInt16 rom_control_info2;
        UInt32 offset_0x70;
        UInt32 offset_0x74;
        UInt32 offset_0x78;
        UInt32 offset_0x7C;
        UInt32 application_end_offset;			// rom size
        UInt32 rom_header_size;
        UInt32 offset_0x88;
        UInt32 offset_0x8C;
        UInt32 offset_0x90;
        UInt32 offset_0x94;
        UInt32 offset_0x98;
        UInt32 offset_0x9C;
        UInt32 offset_0xA0;
        UInt32 offset_0xA4;
        UInt32 offset_0xA8;
        UInt32 offset_0xAC;
        UInt32 offset_0xB0;
        UInt32 offset_0xB4;
        UInt32 offset_0xB8;
        UInt32 offset_0xBC;
        byte[] logo = new byte[156];
        UInt16 logo_crc;
        UInt16 header_crc;
        byte[] zero = new byte[160];

        public string Title { get; set; }

        private void ReadInternal(BinaryReader reader)
        {
            Title = new string(reader.ReadChars(12));
            Gamecode = new string(reader.ReadChars(4));
            makercode = reader.ReadChars(2);
            unitcode = reader.ReadByte();
            devicetype = reader.ReadByte();
            devicecap = reader.ReadByte();
            reserved1 = reader.ReadBytes(9);
            romversion = reader.ReadByte();
            reserved2 = reader.ReadByte();
            arm9_rom_offset = reader.ReadUInt32();
            arm9_entry_address = reader.ReadUInt32();
            arm9_ram_address = reader.ReadUInt32();
            arm9_size = reader.ReadUInt32();
            arm7_rom_offset = reader.ReadUInt32();
            arm7_entry_address = reader.ReadUInt32();
            arm7_entry_address = reader.ReadUInt32();
            arm7_size = reader.ReadUInt32();
            fnt_offset = reader.ReadUInt32();
            fnt_size = reader.ReadUInt32();
            fat_offset = reader.ReadUInt32();
            fat_size = reader.ReadUInt32();
            arm9_overlay_offset = reader.ReadUInt32();
            arm9_overlay_size = reader.ReadUInt32();
            arm7_overlay_offset = reader.ReadUInt32();
            arm7_overlay_size = reader.ReadUInt32();
            rom_control_info1 = reader.ReadBytes(8);
            icon_title_offset = reader.ReadUInt32();
            secure_area_crc = reader.ReadUInt16();
            rom_control_info2 = reader.ReadUInt16();
            offset_0x70 = reader.ReadUInt32();
            offset_0x74 = reader.ReadUInt32();
            offset_0x78 = reader.ReadUInt32();
            offset_0x7C = reader.ReadUInt32();
            application_end_offset = reader.ReadUInt32();
            rom_header_size = reader.ReadUInt32();
            offset_0x88 = reader.ReadUInt32();
            offset_0x8C = reader.ReadUInt32();
            offset_0x90 = reader.ReadUInt32();
            offset_0x94 = reader.ReadUInt32();
            offset_0x98 = reader.ReadUInt32();
            offset_0x9C = reader.ReadUInt32();
            offset_0xA0 = reader.ReadUInt32();
            offset_0xA4 = reader.ReadUInt32();
            offset_0xA8 = reader.ReadUInt32();
            offset_0xAC = reader.ReadUInt32();
            offset_0xB0 = reader.ReadUInt32();
            offset_0xB4 = reader.ReadUInt32();
            offset_0xB8 = reader.ReadUInt32();
            offset_0xBC = reader.ReadUInt32();
            logo = reader.ReadBytes(156);
            logo_crc = reader.ReadUInt16();
            header_crc = reader.ReadUInt16();
            zero = reader.ReadBytes(160);

        }

        public static RomHeader Read(BinaryReader reader)
        {
            var header = new RomHeader();
            header.ReadInternal(reader);
          
            return header;
        }
    };
}